package com.bootx.controller.api;

import com.bootx.common.Result;
import com.bootx.controller.BaseController;
import com.bootx.entity.*;
import com.bootx.pojo.MyChatMessage;
import com.bootx.service.AiRoleChatMessageService;
import com.bootx.service.AiRoleService;
import com.bootx.service.MemberService;
import com.fasterxml.jackson.annotation.JsonView;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.SystemMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * @author black
 */
@RestController
@RequestMapping("/api/chat")
public class ChatController extends BaseController {

    @Resource(name = "openAiStreamingChatModel1")
    private StreamingChatModel streamingChatModel;

    @Resource
    private AiRoleService aiRoleService;

    @Resource
    private MemberService memberService;
    @Resource
    private AiRoleChatMessageService aiRoleChatMessageService;

    @PostMapping
    public Flux<MyChatMessage> chat(String content, Long roleId, HttpServletResponse response, HttpServletRequest request) {
        Member member = memberService.getCurrent(request);
        AiRole aiRole = aiRoleService.find(roleId);

        AiRoleChatMessage aiRoleChatMessage =  new AiRoleChatMessage();
        aiRoleChatMessage.setContent(content);
        aiRoleChatMessage.setAiRole(aiRole);
        aiRoleChatMessage.setMember(member);
        aiRoleChatMessage.setMessageType(MessageType.USER);
        aiRoleChatMessageService.save(aiRoleChatMessage);
        SystemMessage systemMessage = SystemMessage.systemMessage(aiRole.getSystemPrompt());
        String messageId = UUID.randomUUID().toString().replace("-","");
        response.setContentType(MediaType.TEXT_EVENT_STREAM_VALUE+";charset=UTF-8");
        return Flux.create((sink ) -> {
            // 1. 获取历史消息
            List<ChatMessage> messages = aiRoleChatMessageService.getHistory(member,aiRole);
            // 2. 只在第一次对话时添加系统消息
            if (messages.isEmpty()) {
                messages.add(systemMessage);  // 如果是第一次对话，添加系统消息
            }
            // 加入用户的消息
            messages.add(UserMessage.userMessage(content));
            // 3. 通过 AI 模型生成回复，并实时推送给客户端
            streamingChatModel.chat(messages, new StreamingChatResponseHandler() {
                @Override
                public void onPartialResponse(String partialResponse) {
                    sink.next(MyChatMessage.aiMessage(partialResponse,messageId));
                }

                @Override
                public void onCompleteResponse(ChatResponse completeResponse) {
                    System.out.println("\n--- 完成 ---");
                    // 保存到数据库
                    AiRoleChatMessage aiRoleChatMessage =  new AiRoleChatMessage();
                    aiRoleChatMessage.setContent(completeResponse.aiMessage().text());
                    aiRoleChatMessage.setAiRole(aiRoleService.find(roleId));
                    aiRoleChatMessage.setMember(member);
                    aiRoleChatMessage.setMessageType(MessageType.ASSISTANT);
                    aiRoleChatMessageService.save(aiRoleChatMessage);
                    sink.complete();
                }

                @Override
                public void onError(Throwable error) {
                    error.printStackTrace();
                }
            });
        });
    }

    @PostMapping("/history")
    @JsonView({BaseEntity.ListView.class})
    public Result history(Long roleId, HttpServletRequest request) {
        Map<String, Object> map = new HashMap<>();
        Member member = memberService.getCurrent(request);
        AiRole aiRole = aiRoleService.find(roleId);
        map.put("list",aiRoleChatMessageService.findList(member,aiRole));
        return Result.success(map);
    }
}
